/*
 *  author: Honrun
 */
#include "stdint.h"
#include "stdio.h"
#include "gd32w51x.h"
#include "microList.h"
#include "microTime.h"
#include "microTimer.h"



/* 软件定时器头节点 */
MicroListType g_typeMicroListTimerHead = {&g_typeMicroListTimerHead, &g_typeMicroListTimerHead, MICRO_LIST_VALUE_MAX, NULL};



int8_t cMicroTimerSet(MicroTimerTypeDef *ptypeTimer, int64_t lTime, MicroTimerStateEnum state)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop = lMicroTimerGetNow() + lTime;
    ptypeTimer->timeDuration = lTime;
    ptypeTimer->state = state;

    return 0;
}

int8_t cMicroTimerReset(MicroTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cMicroTimerSet(ptypeTimer, ptypeTimer->timeDuration, ptypeTimer->state | MicroTimerOpen);

    return 0;
}

int8_t cMicroTimerReload(MicroTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop += ptypeTimer->timeDuration;
    ptypeTimer->state |= MicroTimerOpen;

    return 0;
}

int8_t cMicroTimerOpen(MicroTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state |= MicroTimerOpen;

    return 0;
}

int8_t cMicroTimerClose(MicroTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state &= ~MicroTimerOpen;

    return 0;
}

int8_t cMicroTimerSetState(MicroTimerTypeDef *ptypeTimer, MicroTimerStateEnum enumState)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state = enumState;

    /* 设置为本次立即触发 */
    if(enumState & MicroTimerOver)
        ptypeTimer->timeStop = lMicroTimerGetNow();

    return 0;
}

MicroTimerStateEnum enumMicroTimerGetState(MicroTimerTypeDef *ptypeTimer)
{
    int64_t ulTimeNow = 0;

    if(ptypeTimer == NULL)
        return MicroTimerError;

    if((ptypeTimer->state & MicroTimerOpen) == 0)
        return MicroTimerClose;

    ulTimeNow = lMicroTimerGetNow();

    if(ulTimeNow >= (ptypeTimer->timeStop))
        return MicroTimerOver;

    return MicroTimerOpen;
}

/* 单位us */
int64_t lMicroTimerGetNow(void)
{
    int64_t lTimeStamp = 0;

    lTimeStamp = lMicroTimeGet();

    return lTimeStamp;
}







int8_t cMicroTimerCreate(MicroTimerTypeDef *ptypeTimer, int64_t lTime, MicroTimerStateEnum state, void (*vCallbackFunction)(void *pvHandle))
{
    int8_t cError = 0;

    if(ptypeTimer == NULL)
        return -1;

    cError |= cMicroTimerSetUs(ptypeTimer, lTime, state);

    cError |= cMicroListInit(&(ptypeTimer->typeList), ptypeTimer->timeStop);

    /* 按顺序插入 */
    cError |= cMicroListInsert(&g_typeMicroListTimerHead, &(ptypeTimer->typeList));

    ptypeTimer->typeList.pElement = ptypeTimer;

    ptypeTimer->vCallbackFunction = vCallbackFunction;

    return cError;
}

int8_t cMicroTimerRemove(MicroTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cMicroListRemove(&(ptypeTimer->typeList));

    return 0;
}

int8_t cMicroTimerMachine(void)
{
    MicroTimerTypeDef *ptypeTimerNow = g_typeMicroListTimerHead.pNext->pElement;
    int8_t cError = 0;

    /* 查询链表第一个元素是否到期 */
    while(enumMicroTimerGetState(ptypeTimerNow) == MicroTimerOver)
    {
        /* 回调函数 */
        if(ptypeTimerNow->vCallbackFunction != NULL)
        {
            ptypeTimerNow->vCallbackFunction(ptypeTimerNow);
        }

        /* 移出链表 */
        cError |= cMicroListRemove(&(ptypeTimerNow->typeList));

        /* 重复计时 */
        if(ptypeTimerNow->state & MicroTimerCircular)
        {
            cError |= cMicroTimerReload(ptypeTimerNow);

            cError |= cMicroListInit(&(ptypeTimerNow->typeList), ptypeTimerNow->timeStop);

            /* 按顺序插入 */
            cError |= cMicroListInsert(&g_typeMicroListTimerHead, &(ptypeTimerNow->typeList));
        }
        /* 单次计时 */
        else
            cError |= cMicroTimerClose(ptypeTimerNow);

        /* 把指针再次指令链表第一个元素（第一个元素总是最早到期） */
        ptypeTimerNow = g_typeMicroListTimerHead.pNext->pElement;
    }

    return cError;
}
